home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 145 / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z / Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin / html / docs / asm / optime.txt < prev   
Text File  |  2000-05-08  |  8KB  |  304 lines

  1. ;----------------------------------------------------------------
  2. ;内容
  3. ;    サブルーチンの所要時間を測るためのルーチンです。
  4. ;    スーパーバイザモードで呼び出して下さい。
  5. ;    Timer-CとTimer-Dを使用するので,Timer-Dが使用中の場合は停止しておいて下さい。
  6. ;
  7. ;呼び出し手順
  8. ;    move.l    #param,-(sp)    ;初期化ルーチンのパラメータ(ループ回数など)
  9. ;    pea.l    tini        ;後始末ルーチン(不要ならば0)
  10. ;    pea.l    init        ;初期化ルーチン(不要ならば0)
  11. ;    pea.l    main        ;計測するルーチン
  12. ;    jsr    optime        ;d0.l=計測するルーチンの所要時間(μs単位で12799まで)
  13. ;    lea.l    (16,sp),sp
  14. ;
  15. ;リンク時の注意事項
  16. ;    lk -e16のように16バイトアラインメントでリンクして下さい。
  17. ;
  18. ;各ルーチンの設定
  19. ;    各ルーチンはスーパーバイザモードで呼ばれます。
  20. ;    sspは復帰アドレスをプッシュする前に16バイト単位にアラインメントされています。
  21. ;    初期化ルーチンから後始末ルーチンまでd0-d7/a0-a5を自由に使って構いません。
  22. ;    a6レジスタはサブルーチンのアドレスとして使用していますが,破壊しても構いません。
  23. ;    初期化ルーチンでレジスタに設定した値はa6を除いてそのまま計測するルーチンに渡されます。
  24. ;    例えば,初期化ルーチンでカウンタを初期化し,計測ルーチンでループを開始できます。
  25. ;
  26. ;各ルーチンの呼び出し順序
  27. ;    初期化ルーチン→計測するルーチン→後始末ルーチンの順序で,2回呼び出します。
  28. ;    1回目は各ルーチンを命令キャッシュに乗せるための準備です。
  29. ;    2回目の,計測するルーチンの所要時間をμs単位で計測します。
  30. ;    なお,所要時間には呼び出しと復帰の時間が含まれています。
  31. ;    一連の呼び出しの間,割り込みは止められています。
  32. ;
  33. ;計測結果
  34. ;    計測結果はd0.lにμs単位で格納されます。
  35. ;    最大計測時間は12799μsです。これを超えると正確に計測できません。
  36. ;    50MHzのとき1clock=0.02μsですから,適当な回数だけループさせるなどして下さい。
  37. ;----------------------------------------------------------------
  38.  
  39.     .cpu    68000
  40.  
  41. ;----------------------------------------------------------------
  42. ;MFPのアドレス
  43. GPIPDR    equ    $00E88001
  44. AER    equ    $00E88003
  45. DDR    equ    $00E88005
  46. IERA    equ    $00E88007
  47. IERB    equ    $00E88009
  48. IPRA    equ    $00E8800B
  49. IPRB    equ    $00E8800D
  50. ISRA    equ    $00E8800F
  51. ISRB    equ    $00E88011
  52. IMRA    equ    $00E88013
  53. IMRB    equ    $00E88015
  54. VECTR    equ    $00E88017
  55. TACR    equ    $00E88019
  56. TBCR    equ    $00E8801B
  57. TCDCR    equ    $00E8801D
  58. TADR    equ    $00E8801F
  59. TBDR    equ    $00E88021
  60. TCDR    equ    $00E88023
  61. TDDR    equ    $00E88025
  62. SCR    equ    $00E88027
  63. UCR    equ    $00E88029
  64. RSR    equ    $00E8802B
  65. TSR    equ    $00E8802D
  66. UDR    equ    $00E8802F
  67.  
  68. ;----------------------------------------------------------------
  69. ;ベクタアドレス
  70. TIMER_D_VECTOR            equ    $0110
  71.  
  72. ;----------------------------------------------------------------
  73. ;間接サブルーチンコール(000用)
  74. jsrr    .macro    dst
  75.     .local    next
  76.     move.l    dst,-(sp)    ;dspがspを参照している場合があるので最初にプッシュする
  77.     move.l    (sp),-(sp)
  78.     move.l    #next,(4,sp)
  79.     rts
  80. next:
  81.     .endm
  82.  
  83. ;----------------------------------------------------------------
  84. ;パラメータの内容
  85.     .offset    0
  86. p_pc        .ds.l    1    ;復帰アドレス
  87. p_main:        .ds.l    1    ;計測するルーチン
  88. p_init:        .ds.l    1    ;初期化ルーチン
  89. p_tini:        .ds.l    1    ;後始末ルーチン
  90. p_param:    .ds.l    1    ;初期化ルーチンのパラメータ(ループ回数など)
  91.     .text
  92.  
  93. ;----------------------------------------------------------------
  94. ;スタックの内容
  95.     .offset    0
  96. v_main:        .ds.l    1    ;計測するルーチン
  97. v_init:        .ds.l    1    ;初期化ルーチン
  98. v_tini:        .ds.l    1    ;後始末ルーチン
  99. v_param:    .ds.l    1    ;初期化ルーチンのパラメータ(ループ回数など)
  100. v_ssp:        .ds.l    1    ;元のスタックポインタ(この位置+16以上)
  101. v_test:        .ds.b    1    ;0=本番,-1=リハーサル
  102. v_tcdcr:    .ds.b    1    ;TCDCRのワーク
  103. v_imrb:        .ds.b    1    ;IMRBのワーク
  104. v_ierb:        .ds.b    1    ;IERBのワーク
  105.     .align    16
  106. v_size:
  107.     .text
  108.  
  109. ;----------------------------------------------------------------
  110. ;計測ルーチン
  111. ;    スーパーバイザモードで呼び出すこと
  112. ;<(4,sp).l:計測するルーチン
  113. ;<(8,sp).l:初期化ルーチン(不要ならば0)
  114. ;<(12,sp).l:後始末ルーチン(不要ならば0)
  115. ;>d0.l:所要時間(単位はμs,0~12799),-1=Timer-Dが使用中
  116. ;----------------------------------------------------------------
  117.     .even
  118. _optime::
  119.     movem.l    d1-d7/a0-a6,-(sp)    ;ここではa6も必要
  120.     lea.l    (4*14,sp),a6        ;pcのアドレス
  121.  
  122. ;Timer-Dの使用状態の確認
  123.     btst.b    #4,IERB
  124.     beq    @f            ;Timer-Dは使用されていない
  125.     movea.l    $1C20.w,a0        ;Humanの先頭
  126.     move.l    (8,a0),d0        ;Humanの末尾
  127.     cmp.l    TIMER_D_VECTOR,d0
  128.     bcc    @f            ;Timer-DはHumanが使用中
  129.     moveq.l    #-1,d0            ;Timer-DはHuman以外が使用中
  130.     bra    99f
  131. @@:
  132.  
  133. ;割り込み禁止
  134.     move.w    sr,-(sp)
  135.     ori.w    #$0700,sr
  136.  
  137. ;ワークの確保とアラインメント
  138.     move.l    sp,d0
  139.     and.l    #$0000000F,d0
  140.     neg.l    d0
  141.     move.l    sp,(-v_size+v_ssp,sp,d0.l)    ;割り込みを止めてあるので,
  142.     lea.l    (-v_size,sp,d0.l),sp    ;この間に割り込みなどでスタックが壊れることはない
  143.  
  144. ;各ルーチンのアドレスをセット
  145.     move.l    (p_main,a6),(v_main,sp)    ;計測するルーチン
  146.  
  147.     lea.l    (dummy_routine,pc),a0
  148.     move.l    (p_init,a6),d0
  149.     beq    @f
  150.     movea.l    d0,a0
  151. @@:    move.l    a0,(v_init,sp)        ;初期化ルーチン
  152.  
  153.     lea.l    (dummy_routine,pc),a0
  154.     move.l    (p_tini,a6),d0
  155.     beq    @f
  156.     movea.l    d0,a0
  157. @@:    move.l    a0,(v_tini,sp)        ;後始末ルーチン
  158.  
  159.     move.l    (p_param,a6),(v_param,sp)    ;初期化ルーチンのパラメータ
  160.  
  161. ;タイマ設定
  162.     move.b    IERB,(v_ierb,sp)
  163.     move.b    IMRB,(v_imrb,sp)
  164.     move.b    TCDCR,(v_tcdcr,sp)
  165.  
  166.     andi.b    #%11001111,IERB        ;Timer-C/D割り込み停止
  167.     andi.b    #%11001111,IMRB        ;Timer-C/D割り込み禁止
  168.  
  169.     sf.b    TCDCR            ;Timer-C/Dカウント停止
  170. @@:    tst.b    TCDCR            ;完全に停止するまで待つ
  171.     bne    @b
  172.  
  173. ;000~010と020~060で処理を分ける
  174. @@:    moveq.l    #1,d0
  175.     .cpu    68020
  176.     and.b    (@b-1,pc,d0.l*2),d0
  177.     .cpu    68000
  178.     bne    measure_020
  179.  
  180. ;000~010用の計測ルーチン
  181. measure_000:
  182.     st.b    (v_test,sp)        ;リハーサル
  183.  
  184. retry_000:
  185.     movea.l    (v_init,sp),a6
  186.     move.l    (v_param,sp),-(sp)
  187.     jsr    (a6)            ;初期化ルーチンを呼ぶ
  188.     addq.l    #4,sp
  189.  
  190.     sf.b    TCDR            ;Timer-Cカウンタクリア
  191. @@:    tst.b    TCDR            ;カウンタが更新されるまで待つ
  192.     bne    @b
  193.     sf.b    TDDR            ;Timer-Dカウンタクリア
  194. @@:    tst.b    TDDR            ;カウンタが更新されるまで待つ
  195.     bne    @b
  196.  
  197.     movea.l    (v_main,sp),a6        ;計測するルーチン
  198.  
  199. ;カウント開始
  200. ;          TCCR TDCR
  201.     move.b    #%0111_0001,TCDCR    ;Timer-C/Dカウント開始
  202.                     ;    Timer-Cは1/200プリスケール(50μs)
  203.                     ;    Timer-Dは1/4プリスケール(1μs)
  204.  
  205. ;計測するルーチンを呼び出す
  206.     jsr    (a6)
  207.  
  208. ;カウント停止
  209.     sf.b    TCDCR            ;Timer-C/Dカウント停止
  210. @@:    tst.b    TCDCR            ;完全に停止するまで待つ
  211.     bne    @b
  212.  
  213.     movea.l    (v_tini,sp),a6
  214.     jsr    (a6)            ;後始末ルーチンを呼ぶ
  215.  
  216.     not.b    (v_test,sp)
  217.     beq    retry_000
  218.  
  219.     bra    measure_done
  220.  
  221. ;020~060用の計測ルーチン
  222.     .cpu    68020
  223. measure_020:
  224.     st.b    (v_test,sp)        ;リハーサル
  225.  
  226. retry_020:
  227.     movea.l    (v_init,sp),a6
  228.     move.l    (v_param,sp),-(sp)
  229.     jsr    (a6)            ;初期化ルーチンを呼ぶ
  230.     addq.l    #4,sp
  231.  
  232.     sf.b    TCDR            ;Timer-Cカウンタクリア
  233. @@:    tst.b    TCDR            ;カウンタが更新されるまで待つ
  234.     bne    @b
  235.     sf.b    TDDR            ;Timer-Dカウンタクリア
  236. @@:    tst.b    TDDR            ;カウンタが更新されるまで待つ
  237.     bne    @b
  238.  
  239.     movea.l    (v_main,sp),a6        ;計測するルーチン
  240.  
  241.     bra    @f
  242.     .align    16
  243.     .ds.w    16-3
  244. @@:
  245.  
  246. ;カウント開始
  247. ;          TCCR TDCR
  248.     move.b    #%0111_0001,TCDCR    ;Timer-C/Dカウント開始
  249.                     ;    Timer-Cは1/200プリスケール(50μs)
  250.                     ;    Timer-Dは1/4プリスケール(1μs)
  251.  
  252. ;計測するルーチンを呼び出す
  253.     jsr    (a6)
  254.  
  255. ;カウント停止
  256.     sf.b    TCDCR            ;Timer-C/Dカウント停止
  257. @@:    tst.b    TCDCR            ;完全に停止するまで待つ
  258.     bne    @b
  259.  
  260.     movea.l    (v_tini,sp),a6
  261.     jsr    (a6)            ;後始末ルーチンを呼ぶ
  262.  
  263.     not.b    (v_test,sp)
  264.     beq    retry_020
  265.  
  266.     .cpu    68000
  267.  
  268. ;計測終わり
  269. measure_done:
  270.  
  271. ;タイマ取得
  272.     moveq.l    #0,d0
  273.     moveq.l    #0,d1
  274.     sub.b    TCDR,d0            ;Timer-Cカウント数
  275.     sub.b    TDDR,d1            ;Timer-Dカウント数(オーバーフローあり)
  276.  
  277. ;タイマ後始末
  278.     move.b    #200,TCDR        ;Timer-Cカウンタ復元
  279.     move.b    #20,TDDR        ;Timer-Dカウンタ復元
  280.     move.b    (v_imrb,sp),IMRB
  281.     move.b    (v_ierb,sp),IERB
  282.     move.b    (v_tcdcr,sp),TCDCR
  283.  
  284. ;ワークの開放
  285.     movea.l    (v_ssp,sp),sp        ;元のスタックポインタ
  286.  
  287. ;割り込み許可
  288.     move.w    (sp)+,sr
  289.  
  290. ;カウンタを合成する
  291.     mulu.w    #50,d0
  292.     cmp.b    d1,d0
  293.     bls    @f
  294.     add.w    #$0100,d0
  295. @@:    move.b    d1,d0
  296.     subq.w    #1,d0
  297.  
  298. 99:    tst.l    d0
  299.     movem.l    (sp)+,d1-d7/a0-a6
  300.     rts
  301.  
  302. dummy_routine:
  303.     rts
  304.